﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Application.DTO;
using AutoMapper;
using Core;
using Core.Entities;
using Core.IPepositories;
using Infrastructure;

namespace Application
{
    public class MenuService : IMenuService
    {
        private readonly IMenuRepository _repositiry;
        private readonly IUserRepository _userRepositiry;
        private readonly IRoleRepository _roleRepositiry;
        private readonly IMapper _mapper;
        private readonly IUnitOfWork _unitOfWork;

        public MenuService(IMenuRepository repository, IUserRepository userRepsoitory, IRoleRepository roleRepsoitory, IUnitOfWork unitOfWork, IMapper mapper)
        {
            _repositiry = repository;
            _userRepositiry = userRepsoitory;
            _roleRepositiry = roleRepsoitory;
            _mapper = mapper;
            _unitOfWork = unitOfWork;
        }
        public void Delete(Guid id)
        {
            _repositiry.Delete(id);
            _unitOfWork.Save();
        }

        public void DeleteBatch(List<Guid> ids)
        {
            _repositiry.Delete(t=>ids.Contains(t.ID));
            _unitOfWork.Save();
        }

        public MenuDTO Get(Guid id)
        {
            return _mapper.Map<MenuDTO>(_repositiry.Get(id));
        }

        public List<MenuDTO> GetAllList()
        {
            var menus = _repositiry.GetList().OrderBy(t => t.SerialNumber);

            return _mapper.Map<List<MenuDTO>>(menus);
        }

        public List<MenuDTO> GetMenusByParent(Guid parentID, int startPage, int pageSize, out int rowCount)
        {
            var menus = _repositiry.LoadPageList(startPage, pageSize, out rowCount, it => it.ParentID == parentID, it => it.SerialNumber);
            return _mapper.Map<List<MenuDTO>>(menus);
        }

        public List<MenuDTO> GetMenusByUser(Guid userId)
        {
            List<MenuDTO> result = new List<MenuDTO>();

            var allMenus = _repositiry.GetList().OrderBy(it => it.SerialNumber);

            //如果是管理员返回所有菜单项
            if (userId == SeedData.AdminID) return _mapper.Map<List<MenuDTO>>(allMenus);

            //得到用户的所有角色
            var user = _userRepositiry.GetWithRoles(userId);

            List<Guid> menuIDs = new List<Guid>();
            //找到所有角色对应的菜单权限，Union去重复
            foreach (var item in user.UserRoles) 
            {
                menuIDs = menuIDs.Union(_roleRepositiry.GetAllMenuListByRole(item.RoleID)).ToList();
            }
            allMenus = allMenus.Where(t => menuIDs.Contains(t.ID)).OrderBy(t => t.SerialNumber);

            return _mapper.Map<List<MenuDTO>>(allMenus);
        }

        public bool InsertOrUpdate(MenuDTO dto)
        {
            var menu = _repositiry.InsertOrUpdate(_mapper.Map<Menu>(dto));
            _unitOfWork.Save();
            return menu == null ? false : true;
        }
    }
}
